package at.codebase.web.servlets.item;

import static at.codebase.web.util.i18n.I18NFactory.i18n;

import java.util.ArrayList;
import java.util.HashMap;

import at.codebase.core.LinkCreator;
import at.codebase.core.Settings;
import at.codebase.core.log.Log;
import at.codebase.db.dao.EItemDao;
import at.codebase.db.entities.EItem;
import at.codebase.security.SecureStringBuilder;
import at.codebase.web.servlets.item.ItemInputStatus.InputStatus;
import at.codebase.web.servlets.item.ItemInputStatus.InputStatusDescription;
import at.codebase.web.servlets.item.ItemInputStatus.InputStatusLatitude;
import at.codebase.web.servlets.item.ItemInputStatus.InputStatusLongitude;
import at.codebase.web.servlets.item.ItemInputStatus.InputStatusPrice;
import at.codebase.web.servlets.item.ItemInputStatus.InputStatusTitle;
import at.codebase.web.templates.ErrorWidget;
import at.codebase.web.templates.MainTemplate;
import at.codebase.web.util.LocalRequest.RequestInformation;
import at.codebase.web.util.URLParameters.ParameterException;
import at.codebase.web.util.servlet.SecureServlet;
import at.codebase.web.util.template.Template;
import at.codebase.web.util.template.TemplateEngine;

@SuppressWarnings("rawtypes")
public class ItemEdit extends SecureServlet {

	@Override
	protected RequestType requestType() {
		return RequestType.POST_AND_GET;
	}

	@Override
	protected void initSecurityLevels(ArrayList<UserLevel> secLevels) {
		secLevels.add(UserLevel.ADMIN);
		secLevels.add(UserLevel.REGISTERED);
	}

	@Override
	protected void processRequestSecurityLevel(RequestInformation requestInfo,
			UserLevel level, RequestType requestType) {
		try {
			long itemId = requestInfo.getParameters().getLong("itemId");
			EItem item = EItemDao.getItemById(new Long(itemId));
			if (item != null) {
				if (level.equals(UserLevel.ADMIN)
						|| item.checkSeller(requestInfo.getUser().getId())) {
					if (requestType.equals(RequestType.POST)) {
						if(!tokenCorrect(requestInfo)) {
							processRequestNoAccess(requestInfo, level);
							return;
						}
						
						HashMap<String, InputStatus> inputStatusMap = new HashMap<String, InputStatus>();

						try {
							inputStatusMap.put(
									"itemTitle",
									new InputStatusTitle(requestInfo
											.getParameters().getString(
													"itemTitle")));
						} catch (ParameterException e) {
							inputStatusMap.put("itemTitle",
									new InputStatusTitle(null));
						}

						try {
							inputStatusMap.put(
									"itemPrice",
									new InputStatusPrice(requestInfo
											.getParameters().getString(
													"itemPrice")));
						} catch (ParameterException e) {
							inputStatusMap.put("itemPrice",
									new InputStatusPrice(null));
						}

						try {
							inputStatusMap.put(
									"itemDescription",
									new InputStatusDescription(requestInfo
											.getParameters().getString(
													"itemDescription")));
						} catch (ParameterException e) {
							inputStatusMap.put("itemDescription",
									new InputStatusDescription(null));
						}

						if (requestInfo.getParameters().isExisting(
								"useLocation")) {
							try {
								inputStatusMap.put(
										"latitude",
										new InputStatusLatitude(requestInfo
												.getParameters().getString(
														"latitude")));
							} catch (ParameterException e) {
								inputStatusMap.put("latitude",
										new InputStatusLatitude(null));
							}

							try {
								inputStatusMap.put(
										"longitude",
										new InputStatusLongitude(requestInfo
												.getParameters().getString(
														"longitude")));
							} catch (ParameterException e) {
								inputStatusMap.put("longitude",
										new InputStatusLongitude(null));
							}
						}

						boolean allValid = true;

						for (String key : inputStatusMap.keySet()) {
							InputStatus inputStatus = inputStatusMap.get(key);
							inputStatus.compile();
							if (inputStatus.isError())
								allValid = false;
						}

						if (allValid) {
							String itemTitle = ((InputStatusTitle) inputStatusMap
									.get("itemTitle")).getValue();
							String itemDescription = ((InputStatusDescription) inputStatusMap
									.get("itemDescription")).getValue();
							double itemPrice = ((InputStatusPrice) inputStatusMap
									.get("itemPrice")).getValue().doubleValue();

							item.setTitle(itemTitle);
							item.setDescription(itemDescription);
							item.setPrice(itemPrice);

							boolean useLocation = requestInfo.getParameters()
									.isExisting("useLocation");
							if (useLocation) {
								double latitude = ((InputStatusLatitude) inputStatusMap
										.get("latitude")).getValue()
										.doubleValue();
								double longitude = ((InputStatusLongitude) inputStatusMap
										.get("longitude")).getValue()
										.doubleValue();
								item.setLocation(latitude, longitude);
							} else {
								item.setLocation(null);
							}
							EItemDao.addItem(item);
							Log.logItem(requestInfo.getUser().getId(), new SecureStringBuilder().appendInsecure("Item (itemid=")
									.appendInsecure(String.valueOf(itemId)).appendInsecure(") was changed by user (userid=")
									.appendInsecure(requestInfo.getUser().getId().toString()).appendInsecure(")").toString());
							redirectTo("/item/" + itemId);
						} else {
							buildPage(requestInfo, item, inputStatusMap);
						}
					} else {
						HashMap<String, InputStatus> inputStatusMap = new HashMap<String, InputStatus>();

						inputStatusMap.put("itemTitle", new InputStatusTitle(
								item.getTitle()));
						inputStatusMap.put("itemPrice", new InputStatusPrice(
								String.valueOf(item.getPrice())));
						inputStatusMap.put(
								"itemDescription",
								new InputStatusDescription(item
										.getDescription()));
						inputStatusMap.put("latitude", new InputStatusLatitude(
								String.valueOf(item.getLatitude())));
						inputStatusMap.put(
								"longitude",
								new InputStatusLatitude(String.valueOf(item
										.getLongitude())));

						buildPage(requestInfo, item, inputStatusMap);
					}
				}
			}
		} catch (ParameterException e) {
			// TODO: Wront parameter.. Maybe Log this
		}

	}

	private void buildPage(RequestInformation requestInfo, EItem item,
			HashMap<String, InputStatus> inputStatusMap) {
		MainTemplate mainTemplate = new MainTemplate(requestInfo, writer());
		mainTemplate.setTitle(i18n(requestInfo.getLocale()).string(
				"itemAdd_add_title"));
		mainTemplate.addJSScript("script_item_edit.js");

		// ErrorWidget
		ErrorWidget errorWidget = new ErrorWidget();
		if (inputStatusMap.get("itemTitle").isError())
			errorWidget.addErrorItem(i18n(requestInfo.getLocale()).string(
					"itemAdd_titleError"));
		if (inputStatusMap.get("itemPrice").isError())
			errorWidget.addErrorItem(i18n(requestInfo.getLocale()).string(
					"itemAdd_priceError"));
		if (inputStatusMap.get("itemDescription").isError())
			errorWidget.addErrorItem(i18n(requestInfo.getLocale()).string(
					"itemAdd_descriptionError"));

		Template editItemTemplate = TemplateEngine
				.getTemplate("item/site_edit_item.html");
		editItemTemplate.setText("randomKey", nextToken());
		editItemTemplate.setHTML("itemLink",
				LinkCreator.itemLink(item.getId(), item.getTitle()));
		editItemTemplate.setText("itemId", item.getId().toString());

		if (errorWidget.hasErrors())
			editItemTemplate.setTemplate("errorWidget", errorWidget);

		editItemTemplate.setHTML("itemTitleValue",
				inputStatusMap.get("itemTitle").getRawString());
		editItemTemplate.setHTML("itemPriceValue",
				inputStatusMap.get("itemPrice").getRawString());
		editItemTemplate.setHTML("itemDescriptionValue",
				inputStatusMap.get("itemDescription").getRawString());

		Template googleMapTemplate = TemplateEngine
				.getTemplate("util/google_map_selection.html");
		googleMapTemplate.setText(
				"script_itemAdd_noSearchResults",
				i18n(requestInfo.getLocale()).string(
						"script_itemAdd_noSearchResults"));
		if (item.getLocation() != null) {
			googleMapTemplate.setText("zoom", String.valueOf(Settings.Util.GoogleMapDefaultZoomLevel));
			googleMapTemplate.setText("latitude", inputStatusMap
					.get("latitude").getRawString());
			googleMapTemplate.setText("longitude",
					inputStatusMap.get("longitude").getRawString());
			googleMapTemplate.setText("hasInitLocation", "1");
			editItemTemplate.setText("useLocationChecked", "checked");
		} else {
			googleMapTemplate.setText("zoom", "0");
			googleMapTemplate.setText("hasInitLocation", "0");
			googleMapTemplate.setText("latitude", "0.0");
			googleMapTemplate.setText("longitude", "0.0");
			editItemTemplate.setText("useLocationChecked", "");
		}
		googleMapTemplate.setText("isFixed", "0");
		editItemTemplate.setTemplate("googleMapSelection", googleMapTemplate);

		mainTemplate.setTemplate("body", editItemTemplate);
		mainTemplate.render(requestInfo.getLocale());
	}

}
